﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using ElfTyping.General;
using ElfTyping.States.GameState.Entities;
using Microsoft.Xna.Framework.Graphics;
using ElfTyping.States.GameState.Effects;
using ElfTyping.States.GameState.PlayerSpells;
using ElfTyping.States.GameState.PlayerPassives;

namespace ElfTyping.States.GameState
{
    public class GameState : State
    {
        Rectangle backgroundRect = new Rectangle(0, 0, 800, 600);
        Texture2D backgroundTexture = TypingGame.Game().Content.Load<Texture2D>(@"Textures\GameState\Background");        
        EventManager eventManager;

        public Player Player { get; private set; }
        public int QuestNumber { get; private set; }
        public int ChapterNumber { get; private set; }

        List<GameEffect> effectList = new List<GameEffect>();
        List<GameEffect> backgroundEffects = new List<GameEffect>();
        List<GameEffect> foregroundEffects = new List<GameEffect>();

        List<SpellIndicatorEntity> spellIndicators = new List<SpellIndicatorEntity>();
        
        List<Enemy> enemyList = new List<Enemy>();
        public int EnemyCount
        {
            get { return enemyList.Count; }
        }
        public List<Enemy> EnemyList { get { return enemyList; } }

        List<WordEntity> wordEntities = new List<WordEntity>();

        GameScript script;

        public GameState(int quest, int chapter)
        {
            eventManager = new EventManager(this, quest, chapter);
            QuestNumber = quest;
            ChapterNumber = chapter;
            script = new GameScript(this);
            EnemiesToAttack = new List<Enemy>();
        }

        public override void InitializeState()
        {
            Player = new Player(new GameScript(this), new Vector2(660, 300));
            //enemySpawner = new EnemySpawner(this);
            BackgroundEffectsToBeStarted = new List<GameEffect>();
            ForegroundEffectsToBeStarted = new List<GameEffect>();

            if (Player.Spells.Count >= 1)
            {
                SpellIndicatorEntity indicatorEntity = new SpellIndicatorEntity(new GameScript(this), new Vector2(750, 200), Player.Spells[0]);
                spellIndicators.Add(indicatorEntity);
                wordEntities.Add(indicatorEntity);
            }

            if (Player.Spells.Count >= 2)
            {
                SpellIndicatorEntity indicatorEntity = new SpellIndicatorEntity(new GameScript(this), new Vector2(750, 400), Player.Spells[1]);
                spellIndicators.Add(indicatorEntity);
                wordEntities.Add(indicatorEntity);
            }
        }

        public override void Draw(Camera camera)
        {
            camera.DrawRectangle(backgroundRect, backgroundTexture);

            if (Player == null)
            {
                return;
            }

            foreach (GameEffect effect in backgroundEffects)
            {
                effect.Draw(camera);
            }

            Player.Draw(camera);

            foreach (Enemy enemy in enemyList)
            {
                enemy.Draw(camera);
            }

            foreach (SpellIndicatorEntity spellIndicator in spellIndicators)
            {
                spellIndicator.Draw(camera);
            }

            foreach (GameEffect effect in foregroundEffects)
            {
                effect.Draw(camera);
            }
        }


        public List<Enemy> EnemiesToBeSpawned { get; private set; }
        public List<GameEffect> ForegroundEffectsToBeStarted { get; private set; }
        public List<GameEffect> BackgroundEffectsToBeStarted { get; private set; }

        public override void Tick(float dt)
        {
            eventManager.Tick(dt);
            Player.Tick(dt);            

            List<Enemy> enemiesToRemove = new List<Enemy>();
            EnemiesToBeSpawned = new List<Enemy>();            

            foreach (Enemy enemy in enemyList)
            {
                enemy.Tick(dt);

                if (enemy.IsActive && (enemy.CenterPosition.X >= Player.CenterPosition.X))
                {
                    enemy.DoAttack();
                    Player.TakeDamage(enemy.Damage);
                }
                else if (enemy.CenterPosition.X > 900)
                {
                    enemiesToRemove.Add(enemy);
                }
            }

            foreach (SpellIndicatorEntity spellIndicator in spellIndicators)
            {
                spellIndicator.Tick(dt);
            }

            List<GameEffect> effectsToRemove = new List<GameEffect>();            

            foreach (GameEffect effect in effectList)
            {
                effect.Tick(dt);

                if (effect.IsDone)
                {
                    effectsToRemove.Add(effect);
                    effect.OnEnd();
                }
            }

            foreach (Enemy enemy in enemiesToRemove)
            {
                RemoveEnemy(enemy);
            }

            foreach (Enemy enemy in EnemiesToBeSpawned)
            {
                AddEnemy(enemy);
            }

            foreach (GameEffect effect in effectsToRemove)
            {
                RemoveEffect(effect);
            }

            foreach (GameEffect effect in ForegroundEffectsToBeStarted)
            {
                AddAndStartEffect(effect, true);
            }

            foreach (GameEffect effect in BackgroundEffectsToBeStarted)
            {
                AddAndStartEffect(effect, false);
            }

            ForegroundEffectsToBeStarted = new List<GameEffect>(); // this must be done at the end since handleinput changes it.
            BackgroundEffectsToBeStarted = new List<GameEffect>(); 
            base.Tick(dt);
        }

        public List<Enemy> EnemiesToAttack { get; private set; }
        public override void HandleInput(InputInfo inputInfo)
        {           
            for (char c = 'A'; c <= 'Z'; c++)
            {
                if (inputInfo.IsKeyJustPressed(c))
                {
                    foreach (WordEntity wordEntity in wordEntities)
                    {
                        if (wordEntity.NextLetter == c)
                        {
                            WordEntity.AcceptLetterResult acceptLetterResult = wordEntity.AcceptLetter();

                            if (acceptLetterResult == WordEntity.AcceptLetterResult.WordFinishedPerfect)
                            {
                                foreach (SpellIndicatorEntity spellIndicator in spellIndicators)
                                {
                                    spellIndicator.GainHealth(1);
                                }
                            }

                            if (acceptLetterResult != WordEntity.AcceptLetterResult.Failed)
                            {
                                foreach (PlayerPassive passive in Player.Passives)
                                {
                                    if (wordEntity is Enemy) {
                                        passive.OnShoot(script, (Enemy)wordEntity, (acceptLetterResult == WordEntity.AcceptLetterResult.WordFinishedPerfect));
                                    }
                                }
                            }
                            
                        }
                        else
                        {
                            wordEntity.ResetNextLetter();
                        }
                    }                    
                }
            }

            foreach (Enemy enemy in EnemiesToAttack)
            {
                AttackEnemy(enemy);
            }
            EnemiesToAttack = new List<Enemy>();
        }

        public void AddEnemy(Enemy enemy)
        {
            enemyList.Add(enemy);
            enemyList.Sort((a, b) => a.CenterPosition.Y.CompareTo(b.CenterPosition.Y));

            wordEntities.Add(enemy);
        }

        private void AttackEnemy(Enemy enemy)
        {
            Player.Shoot();
            enemy.TakeDamage(Player.TotalDamage);

            ForegroundEffectsToBeStarted.Add(new ArrowEffect(Player, enemy));
        }

        public void RemoveEnemy(Enemy enemy)
        {
            enemyList.Remove(enemy);
            wordEntities.Remove(enemy);
        }

        public void AddAndStartEffect(GameEffect effect, bool isForegroundEffect)
        {
            effectList.Add(effect);
            effect.OnStart();

            if (isForegroundEffect)
            {
                foregroundEffects.Add(effect);
            }
            else
            {
                backgroundEffects.Add(effect);
            }
        }

        public void RemoveEffect(GameEffect effect)
        {
            effectList.Remove(effect);

            backgroundEffects.Remove(effect);
            foregroundEffects.Remove(effect);
        }

        public void GainExperience(int experienceGain)
        {
            Player.GainExperience(experienceGain);
        }

        public void AddEventIn(float secondsFromNow, EventManager.EventAction action)
        {
            eventManager.AddEventIn(secondsFromNow, action);
        }

        public class EventManager
        {
            GameState gameState;
            /*
            SortedDictionary<float, EnemySpawnMethod> _events = null;
            SortedDictionary<float, EnemySpawnMethod> Events
            {
                get
                {
                    if (_events == null)
                    {
                        _events = new SortedDictionary<float, EnemySpawnMethod>() {
                            //{0.1f, new EnemySpawnMethod(SpawnHardRogue)},
                            {100f, new EnemySpawnMethod(SpawnHardBasicEnemy)},
                            {110f, new EnemySpawnMethod(SpawnHardBasicEnemy)},
                            {115f, new EnemySpawnMethod(SpawnHardBasicEnemy)},
                            {120f, new EnemySpawnMethod(SpawnHardBasicEnemy)},
                            {125f, new EnemySpawnMethod(SpawnHardBasicEnemy)},
                            {130f, new EnemySpawnMethod(SpawnHardBasicEnemy)},
                            {135f, new EnemySpawnMethod(SpawnHardBasicEnemy)},
                            {140f, new EnemySpawnMethod(SpawnHardBasicEnemy)},
                            {145f, new EnemySpawnMethod(SpawnEasyBasicEnemy)},
                            {150f, new EnemySpawnMethod(SpawnEasyBasicEnemy)},
                            {155f, new EnemySpawnMethod(SpawnEasyBasicEnemy)}
                        };
                    }

                    return _events;
                }
            }
             */
            // TODO: switch this over to a SortedList?
            List<KeyValuePair<float, EventAction>> Events;

            float totalTime = 0;
            Random random = new Random();

            public EventManager(GameState gState, int quest, int chapter)
            {
                gameState = gState;
                Events = EventGenerators[new Point(quest, chapter)]();
            }

            public void Tick(float dt)
            {
                bool noEventsInNextSecond = true;

                float eventTime = -1;
                while (Events.Count > 0 && eventTime <= totalTime + 1)
                {
                    eventTime = Events[0].Key;

                    if (eventTime <= totalTime + dt)
                    {
                        Events[0].Value(); // we just went over an event, so trigger it.
                        Events.RemoveAt(0);
                    }
                    else if (eventTime <= totalTime + 1)
                    {
                        noEventsInNextSecond = false;
                        break;
                    }
                }

                if (Events.Count == 0 && gameState.EnemyCount == 0)
                {
                    gameState.ChangeStateAfterTick(new EndOfChapterState(gameState, true), true);
                } else if (noEventsInNextSecond && gameState.EnemyCount == 0)
                {
                    SpawnEasyBasicEnemy();
                }

                totalTime += dt;
            }

            public delegate void EventAction();
            private void SpawnSpecificEnemy(Enemy enemy, EventAction spawnMethod)
            {
                bool foundGoodSpot = false;
                for (int attemptsLeft = 20; !foundGoodSpot && attemptsLeft > 0; attemptsLeft++) // 20 random attempts to place an enemy
                {
                    enemy.MoveCenter(enemy.CenterPosition.X, random.Next(160, 400));
                    if (gameState.enemyList.Find(e => e.DrawBox.Intersects(enemy.DrawBox)) == null)
                    {
                        foundGoodSpot = true;
                    }
                }

                if (foundGoodSpot)
                {
                    gameState.AddEnemy(enemy);
                }
                else
                {
                    AddEventIn(0.5f, spawnMethod); // try spawning again in a bit
                }
            }

            public void AddEventIn(float secondsFromNow, EventAction action)
            {
                float time = totalTime + secondsFromNow;

                for (int i = 0; i < Events.Count; i++)
                {
                    if (totalTime + 0.5f < Events[i].Key)
                    {
                        Events.Insert(i, NewPair(time, action));
                        return;
                    }
                }

                Events.Add(NewPair(time, action));
            }

            private GameScript NewGameScript()
            {
                return new GameScript(gameState);
            }

            private Vector2 NewPosition()
            {
                return new Vector2(-50, 0);
            }

            private Vector2 NewRoguePosition()
            {
                return new Vector2(random.Next(200, 400), 0);
            }

            public void SpawnEasyBasicEnemy()
            {
                SpawnSpecificEnemy(new BasicEnemy(NewGameScript(), NewPosition(), EnemyDifficulty.Easy), new EventAction(SpawnEasyBasicEnemy));
            }

            public void SpawnMediumBasicEnemy()
            {
                SpawnSpecificEnemy(new BasicEnemy(NewGameScript(), NewPosition(), EnemyDifficulty.Medium), new EventAction(SpawnMediumBasicEnemy));
            }

            public void SpawnHardBasicEnemy()
            {
                SpawnSpecificEnemy(new BasicEnemy(NewGameScript(), NewPosition(), EnemyDifficulty.Hard), new EventAction(SpawnHardBasicEnemy));
            }

            public void SpawnEasySummoner()
            {
                SpawnSpecificEnemy(new SummonerEnemy(NewGameScript(), NewPosition(), EnemyDifficulty.Easy), new EventAction(SpawnEasySummoner));
            }

            public void SpawnMediumSummoner()
            {
                SpawnSpecificEnemy(new SummonerEnemy(NewGameScript(), NewPosition(), EnemyDifficulty.Medium), new EventAction(SpawnMediumSummoner));
            }

            public void SpawnHardSummoner()
            {
                SpawnSpecificEnemy(new SummonerEnemy(NewGameScript(), NewPosition(), EnemyDifficulty.Hard), new EventAction(SpawnHardSummoner));
            }

            public void SpawnEasyRogue()
            {
                SpawnSpecificEnemy(new RogueEnemy(NewGameScript(), NewRoguePosition(), EnemyDifficulty.Easy), new EventAction(SpawnEasyRogue));
            }

            public void SpawnMediumRogue()
            {
                SpawnSpecificEnemy(new RogueEnemy(NewGameScript(), NewRoguePosition(), EnemyDifficulty.Medium), new EventAction(SpawnMediumRogue));
            }

            public void SpawnHardRogue()
            {
                SpawnSpecificEnemy(new RogueEnemy(NewGameScript(), NewRoguePosition(), EnemyDifficulty.Hard), new EventAction(SpawnHardRogue));
            }

            public void SpawnTibarn()
            {
                gameState.AddEnemy(new TibarnEnemy(NewGameScript(), new Vector2(-50, 300), this));
            }

            private KeyValuePair<float, EventAction> NewPair(float time, EventAction method)
            {
                return new KeyValuePair<float, EventAction>(time, method);
            }

            private Dictionary<Point, EventGenerator> EventGenerators
            {
                get
                {
                    return new Dictionary<Point, EventGenerator>()
                    {
                        {new Point(1, 1), new EventGenerator(Events1_1)},
                        {new Point(1, 2), new EventGenerator(Events1_2)},
                        {new Point(1, 3), new EventGenerator(Events1_3)},
                        {new Point(1, 4), new EventGenerator(Events1_4)},
                        {new Point(1, 5), new EventGenerator(Events1_5)},
                        {new Point(1, 6), new EventGenerator(Events1_6)},
                        {new Point(1, 7), new EventGenerator(Events1_7)},
                        {new Point(1, 8), new EventGenerator(Events1_8)}
                    };
                }
            }

        

            delegate List<KeyValuePair<float, EventAction>> EventGenerator();
            private List<KeyValuePair<float, EventAction>> Events1_1()
            {
                return new List<KeyValuePair<float, EventAction>>()
                {
                    {NewPair(10, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(19, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(28, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(37, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(45, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(53, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(53, new EventAction(SpawnEasyBasicEnemy))},

                    {NewPair(61, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(68, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(75, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(82, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(88, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(94, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(100, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(100, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(114, new EventAction(SpawnEasyBasicEnemy))},

                    {NewPair(120, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(126, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(132, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(139, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(142, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(145, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(158, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(164, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(168, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(172, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(176, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(180, new EventAction(SpawnEasyBasicEnemy))},
                };
            }

            private List<KeyValuePair<float, EventAction>> Events1_2()
            {
                return new List<KeyValuePair<float, EventAction>>()
                {
                    {NewPair(0.5f, new EventAction(SpawnEasySummoner))},
                    {NewPair(10, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(19, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(20, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(26, new EventAction(SpawnEasySummoner))},
                    {NewPair(35, new EventAction(SpawnEasySummoner))},
                    {NewPair(45, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(53, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(53, new EventAction(SpawnEasyBasicEnemy))},

                    {NewPair(61, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(70, new EventAction(SpawnEasySummoner))},
                    {NewPair(77, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(82, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(88, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(89, new EventAction(SpawnEasySummoner))},
                    {NewPair(94, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(100, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(100, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(112, new EventAction(SpawnEasySummoner))},

                    {NewPair(120, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(126, new EventAction(SpawnEasySummoner))},
                    {NewPair(132, new EventAction(SpawnEasySummoner))},
                    {NewPair(139, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(145, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(158, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(164, new EventAction(SpawnEasySummoner))},
                    {NewPair(168, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(176, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(180, new EventAction(SpawnEasySummoner))},
                    {NewPair(181, new EventAction(SpawnEasySummoner))},
                };
            }

            private List<KeyValuePair<float, EventAction>> Events1_3()
            {
                return new List<KeyValuePair<float, EventAction>>()
                {
                    {NewPair(0.5f, new EventAction(SpawnEasySummoner))},
                    {NewPair(10, new EventAction(SpawnEasySummoner))},
                    {NewPair(19, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(20, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(26, new EventAction(SpawnEasySummoner))},
                    {NewPair(28, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(35, new EventAction(SpawnEasySummoner))},
                    {NewPair(37, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(45, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(53, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(53, new EventAction(SpawnEasyBasicEnemy))},

                    {NewPair(61, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(68, new EventAction(SpawnEasySummoner))},
                    {NewPair(70, new EventAction(SpawnEasySummoner))},
                    {NewPair(77, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(82, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(88, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(89, new EventAction(SpawnEasySummoner))},
                    {NewPair(94, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(100, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(100, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(114, new EventAction(SpawnEasyBasicEnemy))},

                    {NewPair(120, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(126, new EventAction(SpawnEasySummoner))},
                    {NewPair(129, new EventAction(SpawnEasySummoner))},
                    {NewPair(132, new EventAction(SpawnEasySummoner))},
                    {NewPair(139, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(142, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(145, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(158, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(164, new EventAction(SpawnEasySummoner))},
                    {NewPair(168, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(172, new EventAction(SpawnEasySummoner))},
                    {NewPair(176, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(180, new EventAction(SpawnEasySummoner))},
                };
            }

            private List<KeyValuePair<float, EventAction>> Events1_4()
            {
                return new List<KeyValuePair<float, EventAction>>()
                {
                    {NewPair(0, new EventAction(SpawnMediumBasicEnemy))},
                    {NewPair(10, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(19, new EventAction(SpawnEasySummoner))},
                    {NewPair(28, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(37, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(45, new EventAction(SpawnEasySummoner))},
                    {NewPair(53, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(53, new EventAction(SpawnMediumBasicEnemy))},

                    {NewPair(61, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(68, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(75, new EventAction(SpawnMediumBasicEnemy))},
                    {NewPair(82, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(88, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(94, new EventAction(SpawnMediumBasicEnemy))},
                    {NewPair(100, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(100, new EventAction(SpawnEasySummoner))},
                    {NewPair(114, new EventAction(SpawnEasyBasicEnemy))},

                    {NewPair(120, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(126, new EventAction(SpawnMediumBasicEnemy))},
                    {NewPair(132, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(139, new EventAction(SpawnEasySummoner))},
                    {NewPair(142, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(145, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(158, new EventAction(SpawnMediumBasicEnemy))},
                    {NewPair(164, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(168, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(172, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(176, new EventAction(SpawnMediumBasicEnemy))},
                    {NewPair(180, new EventAction(SpawnMediumBasicEnemy))},
                };
            }

            private List<KeyValuePair<float, EventAction>> Events1_5()
            {
                return new List<KeyValuePair<float, EventAction>>()
                {
                    {NewPair(0, new EventAction(SpawnMediumBasicEnemy))},
                    {NewPair(10, new EventAction(SpawnMediumBasicEnemy))},
                    {NewPair(19, new EventAction(SpawnEasySummoner))},
                    {NewPair(28, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(37, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(45, new EventAction(SpawnEasySummoner))},
                    {NewPair(53, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(53, new EventAction(SpawnMediumBasicEnemy))},

                    {NewPair(61, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(68, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(75, new EventAction(SpawnMediumBasicEnemy))},
                    {NewPair(82, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(88, new EventAction(SpawnMediumBasicEnemy))},
                    {NewPair(94, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(100, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(100, new EventAction(SpawnEasySummoner))},
                    {NewPair(114, new EventAction(SpawnMediumBasicEnemy))},

                    {NewPair(120, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(126, new EventAction(SpawnMediumBasicEnemy))},
                    {NewPair(132, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(139, new EventAction(SpawnEasySummoner))},
                    {NewPair(142, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(145, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(158, new EventAction(SpawnMediumBasicEnemy))},
                    {NewPair(164, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(168, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(172, new EventAction(SpawnEasySummoner))},
                    {NewPair(176, new EventAction(SpawnMediumBasicEnemy))},
                    {NewPair(180, new EventAction(SpawnMediumBasicEnemy))},
                };
            }

            private List<KeyValuePair<float, EventAction>> Events1_6()
            {
                return new List<KeyValuePair<float, EventAction>>()
                {
                    {NewPair(0, new EventAction(SpawnEasyRogue))},
                    {NewPair(10, new EventAction(SpawnMediumBasicEnemy))},
                    {NewPair(19, new EventAction(SpawnEasySummoner))},
                    {NewPair(28, new EventAction(SpawnEasyRogue))},
                    {NewPair(37, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(45, new EventAction(SpawnEasySummoner))},
                    {NewPair(53, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(53, new EventAction(SpawnMediumBasicEnemy))},

                    {NewPair(61, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(68, new EventAction(SpawnEasyRogue))},
                    {NewPair(75, new EventAction(SpawnMediumBasicEnemy))},
                    {NewPair(82, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(88, new EventAction(SpawnMediumBasicEnemy))},
                    {NewPair(94, new EventAction(SpawnEasyRogue))},
                    {NewPair(100, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(100, new EventAction(SpawnEasySummoner))},
                    {NewPair(114, new EventAction(SpawnMediumBasicEnemy))},

                    {NewPair(120, new EventAction(SpawnEasyRogue))},
                    {NewPair(126, new EventAction(SpawnMediumBasicEnemy))},
                    {NewPair(132, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(139, new EventAction(SpawnEasySummoner))},
                    {NewPair(142, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(145, new EventAction(SpawnEasyRogue))},
                    {NewPair(158, new EventAction(SpawnMediumBasicEnemy))},
                    {NewPair(164, new EventAction(SpawnEasyRogue))},
                    {NewPair(168, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(172, new EventAction(SpawnEasySummoner))},
                    {NewPair(176, new EventAction(SpawnMediumBasicEnemy))},
                    {NewPair(180, new EventAction(SpawnMediumBasicEnemy))},
                };
            }

            private List<KeyValuePair<float, EventAction>> Events1_7()
             {
                return new List<KeyValuePair<float, EventAction>>()
                {
                    {NewPair(0, new EventAction(SpawnMediumRogue))},
                    {NewPair(10, new EventAction(SpawnMediumBasicEnemy))},
                    {NewPair(19, new EventAction(SpawnEasySummoner))},
                    {NewPair(28, new EventAction(SpawnEasyRogue))},
                    {NewPair(37, new EventAction(SpawnMediumRogue))},
                    {NewPair(45, new EventAction(SpawnEasySummoner))},
                    {NewPair(53, new EventAction(SpawnEasyRogue))},
                    {NewPair(53, new EventAction(SpawnMediumBasicEnemy))},

                    {NewPair(61, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(68, new EventAction(SpawnEasyRogue))},
                    {NewPair(75, new EventAction(SpawnMediumBasicEnemy))},
                    {NewPair(82, new EventAction(SpawnMediumRogue))},
                    {NewPair(88, new EventAction(SpawnMediumBasicEnemy))},
                    {NewPair(94, new EventAction(SpawnEasyRogue))},
                    {NewPair(100, new EventAction(SpawnEasyRogue))},
                    {NewPair(100, new EventAction(SpawnEasySummoner))},
                    {NewPair(114, new EventAction(SpawnMediumBasicEnemy))},

                    {NewPair(120, new EventAction(SpawnEasyRogue))},
                    {NewPair(126, new EventAction(SpawnMediumBasicEnemy))},
                    {NewPair(132, new EventAction(SpawnMediumRogue))},
                    {NewPair(139, new EventAction(SpawnEasySummoner))},
                    {NewPair(142, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(145, new EventAction(SpawnEasyRogue))},
                    {NewPair(158, new EventAction(SpawnMediumBasicEnemy))},
                    {NewPair(164, new EventAction(SpawnMediumRogue))},
                    {NewPair(168, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(172, new EventAction(SpawnEasySummoner))},
                    {NewPair(176, new EventAction(SpawnMediumBasicEnemy))},
                    {NewPair(180, new EventAction(SpawnMediumBasicEnemy))},
                    {NewPair(182, new EventAction(SpawnMediumBasicEnemy))}
                };
            }

            private List<KeyValuePair<float, EventAction>> Events1_8()
            {
                //return new List<KeyValuePair<float, EventAction>>()
                //{
                //    {NewPair(0.5f, new EventAction(SpawnTibarn))}
                //};
                return new List<KeyValuePair<float, EventAction>>()
                {
                    {NewPair(0, new EventAction(SpawnMediumRogue))},
                    {NewPair(10, new EventAction(SpawnMediumBasicEnemy))},
                    {NewPair(19, new EventAction(SpawnEasySummoner))},
                    {NewPair(28, new EventAction(SpawnEasyRogue))},
                    {NewPair(37, new EventAction(SpawnMediumRogue))},
                    {NewPair(45, new EventAction(SpawnEasySummoner))},
                    {NewPair(53, new EventAction(SpawnEasyRogue))},
                    {NewPair(53, new EventAction(SpawnMediumBasicEnemy))},

                    {NewPair(61, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(68, new EventAction(SpawnEasyRogue))},
                    {NewPair(75, new EventAction(SpawnMediumBasicEnemy))},
                    {NewPair(82, new EventAction(SpawnMediumRogue))},
                    {NewPair(88, new EventAction(SpawnMediumBasicEnemy))},
                    {NewPair(94, new EventAction(SpawnEasyRogue))},
                    {NewPair(100, new EventAction(SpawnEasyRogue))},
                    {NewPair(100, new EventAction(SpawnEasySummoner))},
                    {NewPair(114, new EventAction(SpawnMediumBasicEnemy))},

                    {NewPair(120, new EventAction(SpawnEasyRogue))},
                    {NewPair(126, new EventAction(SpawnMediumBasicEnemy))},
                    {NewPair(132, new EventAction(SpawnMediumRogue))},
                    {NewPair(139, new EventAction(SpawnEasySummoner))},
                    {NewPair(142, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(145, new EventAction(SpawnEasyRogue))},
                    {NewPair(158, new EventAction(SpawnMediumBasicEnemy))},
                    {NewPair(164, new EventAction(SpawnMediumRogue))},
                    {NewPair(168, new EventAction(SpawnEasyBasicEnemy))},
                    {NewPair(172, new EventAction(SpawnEasySummoner))},
                    {NewPair(176, new EventAction(SpawnMediumBasicEnemy))},
                    {NewPair(180, new EventAction(SpawnMediumBasicEnemy))},
                    {NewPair(182, new EventAction(SpawnMediumBasicEnemy))}
                };
            }
        }
    }
}
